package io.dshubs.archives.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.dshubs.archives.dao.ArchiveBaseStoreMapper;
import io.dshubs.archives.dao.ArchiveWarehouseLocationMapper;
import io.dshubs.archives.entity.ArchiveBaseStore;
import io.dshubs.archives.entity.ArchiveWarehouseLocation;
import io.dshubs.archives.service.ArchiveWarehouseLocationService;
import io.dshubs.commons.mybatis.enums.DelFlagEnum;
import io.dshubs.commons.mybatis.service.impl.BaseServiceImpl;
import io.dshubs.commons.security.context.TenantContext;
import io.dshubs.commons.security.user.SecurityUser;
import io.dshubs.commons.security.user.UserDetail;
import io.dshubs.commons.tools.constant.Constant;
import io.dshubs.commons.tools.page.PageData;
import io.dshubs.commons.tools.utils.ConvertUtils;
import io.dshubs.commons.tools.validator.group.AddGroup;
import io.dshubs.commons.tools.validator.group.UpdateGroup;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 密架货位表 服务实现类
 * </p>
 *
 * @author tan
 * @since 2021-08-17
 */
@Service
public class ArchiveWarehouseLocationServiceImpl extends BaseServiceImpl<ArchiveWarehouseLocationMapper, ArchiveWarehouseLocation> implements ArchiveWarehouseLocationService {

    @Autowired
    private ArchiveBaseStoreMapper archiveBaseStoreMapper;

    @Override
    public PageData<ArchiveWarehouseLocation> page(Map<String, Object> params) {
        IPage<ArchiveWarehouseLocation> page = baseDao.selectPage(
                getPage(params, Constant.CREATE_DATE, false),
                getWrapper(params)
        );

        return getPageData(page, ArchiveWarehouseLocation.class);
    }

    private QueryWrapper<ArchiveWarehouseLocation> getWrapper(Map<String, Object> params){
        String warehouseId = (String)params.get("warehouseId");
        String zoneId = (String)params.get("zoneId");
        String code = (String)params.get("code");
        QueryWrapper<ArchiveWarehouseLocation> wrapper = new QueryWrapper<>();
        wrapper.eq(Constant.DEL_FLAG, DelFlagEnum.NORMAL.value());
        wrapper.like(StringUtils.isNotBlank(warehouseId), "warehouse_id", warehouseId);
        wrapper.eq(StringUtils.isNotBlank(zoneId),"zone_id",zoneId);
        wrapper.eq(StringUtils.isNotBlank(code),"code",code);
        wrapper.eq("tenant_code", TenantContext.getTenantCode(SecurityUser.getUser()));
        wrapper.orderByAsc("layer_no,column_no");
        return wrapper;
    }

    @Override
    public void save(ArchiveWarehouseLocation location) {
        List<ArchiveWarehouseLocation > res = new ArrayList<>();
        Integer columnNo = location.getColumnNo();
        Integer layerNo = location.getLayerNo();
        for (int i=1;i<= layerNo;i++) {
            for (int j=1;j<= columnNo;j++) {
                ArchiveWarehouseLocation newLocation = new ArchiveWarehouseLocation();
                BeanUtils.copyProperties(location,newLocation);
                newLocation.setCode("KW-"+location.getSegmentNo()+"-"+location.getLayerNo()+"-"+location.getColumnNo());
                newLocation.setId(IdWorker.getId());
                newLocation.setColumnNo(j);
                newLocation.setLayerNo(i);
                newLocation.setLocationStatus("EMPTY");
                newLocation.setStatus("ENABLED");
                newLocation.setInoutLock("UNLOCKED");
                res.add(newLocation);
            }
        }
      this.baseDao.insertBatch(res);
    }

    @Override
    public List<Map<String, Object>> group(Map<String, Object> params) {
        List<Map<String, Object>> resList = new ArrayList<>();
        Map<String, List<ArchiveWarehouseLocation>> segmentNoMap = new HashMap<>(16);
        String zoneId = (String)params.get("warehouseZoneId");
        String warehouseId = (String)params.get("warehouseId");
        String segmentNo = (String)params.get("segmentNo");
        QueryWrapper<ArchiveWarehouseLocation> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(zoneId)) {
            queryWrapper.eq("zone_id",zoneId);
        }
        if(StringUtils.isNotEmpty(warehouseId)) {
            queryWrapper.eq("warehouse_id",warehouseId);
        }
        if(StringUtils.isNotEmpty(segmentNo)) {
            queryWrapper.like("segment_no",segmentNo);
        }
        queryWrapper.orderByAsc("segment_no");
        List<ArchiveWarehouseLocation> locationList = this.baseDao.selectList(queryWrapper);
        if(CollectionUtils.isNotEmpty(locationList)) {
            segmentNoMap  = locationList.stream().collect(Collectors.groupingBy(ArchiveWarehouseLocation::getSegmentNo, Collectors.toList()));
        }
        segmentNoMap.forEach((k,v)->{
            HashMap<String, Object> map = new HashMap<>(16);
            map.put("segmentNo",k);
            map.put("locationList",v);
            resList.add(map);
        });
        return resList;
    }

    @Override
    public List<ArchiveWarehouseLocation> getBySegmentNo(Map<String, Object> params ) {
        String segmentNo = (String)params.get("segmentNo");
        String code = (String)params.get("code");
        QueryWrapper<ArchiveWarehouseLocation> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(segmentNo)) {
            queryWrapper.eq("segment_no", segmentNo);
        }
        if(StringUtils.isNotEmpty(code)) {
            queryWrapper.like("code", code);
        }
        queryWrapper.orderByAsc("code");
        List<ArchiveWarehouseLocation> warehouseLocationList = this.baseDao.selectList(queryWrapper);
       if(CollectionUtils.isNotEmpty(warehouseLocationList)) {
           warehouseLocationList.forEach(item->{
               List<ArchiveBaseStore> stores = archiveBaseStoreMapper.selectList(new QueryWrapper<ArchiveBaseStore>().eq(
                       "location_id", item.getId()));
               item.setUsableHasCapacity(stores.size());
           });
       }
        return warehouseLocationList;
    }

}
